const arr1 = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']
const arr2 = [
  'ten',
  'eleven',
  'twelve',
  'thirteen',
  'fourteen',
  'fifteen',
  'sixteen',
  'seventeen',
  'eighteen',
  'nighteen'
]
const arr3 = ['twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'nighty']
const arr4 = ['hundred', 'thousand', 'million', 'billion', 'trillion', 'quadrillion']

/***********************************************************************************
 * @description: 阿拉伯数字转成英文读法
 * @param {number} number 正整数，最高18位数
 * @return {string} 数字的英语读法
 ***********************************************************************************/
const useNumberToEnglis = (number: Nullable<number> | undefined): string => {
  // 如果不为数字直接返回空字符串
  if (typeof number !== 'number') return ''
  // 判断是否为负数
  const isMinus = number < 0
  const result: Array<string> = [] //? 储存转化后结果
  // 把数字转换为千分位
  const str = toThousands(number)
  const splitStrArr = str.split(',')
  let signIndex = 0 //? 记录当前数字位数（百千万...）
  for (let index = splitStrArr.length - 1; index >= 0; index--) {
    //倒着遍历
    let res = ''
    // 如果当前字符串转成number后是0(即字符串为'000')index--和判断位数的signIndex++，减少运行次数
    while (parseInt(splitStrArr[index]) === 0) {
      if (splitStrArr.length === 1) return 'zero'
      signIndex++
      index--
    }
    // 把当前组的字符串分割为单个字符
    const numStrArr = splitStrArr[index].split('')
    if (numStrArr.length > 2) {
      // 是三位数按三位数处理
      res = tripleNumEngFormat(numStrArr)
    } else if (numStrArr.length == 2) {
      // 是两位数按两位数处理
      res = doubleNumEngFormat(numStrArr)
    } else {
      // 按个位处理
      res = sigleNumEngFormat(numStrArr)
    }
    if (signIndex > 0) {
      //百位数已处理，因此从千位开始
      res += ' ' + arr4[signIndex]
      if (parseInt(splitStrArr[index]) === 0) res = ''
    }
    signIndex++
    result.unshift(res)
  }
  // 为负数前面加Minus
  isMinus ? result.unshift('Minus ') : ''
  return result.join(',').toUpperCase() + ' ONLY'
}

/***********************************************************************************
 * @description: 三位数转英文
 * @param {*} numStrArr 经过分割的数字字符串数组【百位，十位，个位】
 * @return {*}
 ***********************************************************************************/
function tripleNumEngFormat(numStrArr) {
  let res = ''
  if (numStrArr[0] >= 1) {
    //处理百位上的数
    res += arr1[numStrArr[0]] + ' ' + arr4[0]
    if (numStrArr[1] > 0 || numStrArr[2] > 0) res += ' and '
  }
  if (numStrArr[1] > 1) {
    //处理十位上的2以上的数（20-99）
    res += arr3[numStrArr[1] - 2]
    if (numStrArr[2] > 0) {
      res += '-' + arr1[numStrArr[2]]
    }
  } else if (numStrArr[1] == 1) {
    //处理十位上为1的数（10-19）
    res += arr2[numStrArr[2]]
  } else {
    //处理个位上的数
    if (numStrArr[2] == 0) {
      return (res += '')
    }
    res += arr1[numStrArr[2]]
  }
  return res
}

/***********************************************************************************
 * @description: 两位数转英文
 * @param {*} numStrArr 经过分割的数字数组【百位，十位】
 * @return {*}
 ***********************************************************************************/
function doubleNumEngFormat(numStrArr) {
  let res = ''
  if (numStrArr[0] > 1) {
    //处理20以上的数字
    res += arr3[numStrArr[0] - 2]
    if (numStrArr[1] > 0) {
      //处理不为整十的数字
      res += '-' + arr1[numStrArr[1]]
    }
  } else {
    //处理10-19的数字
    res += arr2[numStrArr[1]]
  }
  return res
}

/***********************************************************************************
 * @description: 个位数转英文
 * @param {*} numStrArr 经过分割的数字数组
 * @return {*}
 ***********************************************************************************/
function sigleNumEngFormat(numStrArr) {
  if (numStrArr[0] === 0) return ''
  return arr1[numStrArr[0]]
}

/***********************************************************************************
 * @description: 把数字转成千分位
 * @param {*} number
 * @return {*}
 ***********************************************************************************/
function toThousands(number) {
  let numStr = (number || 0).toString(),
    result = ''
  while (numStr.length > 3) {
    // 从数组后面往前数，每三个就分割加上逗号
    result = ',' + numStr.slice(-3) + result
    // 让numStr剪掉后面三个字符
    numStr = numStr.slice(0, numStr.length - 3)
  }
  if (numStr) {
    result = numStr + result
  }
  return result
}

export default useNumberToEnglis
